String.prototype.removeTags = function () {
    return this.replace(/<([^>]+)>/g,'');
} 

var tabs = $("#rooms").tabs({
    tabTemplate: "<li><a href='#"+"{href}'>#"+"{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>"
});

$(".chat-content > .participants > ul").prepend('<li class="active drop-people-here"><a title="Drag people here"></a></li>');

var addDroppablePeople = function (jQueryElement) {
    jQueryElement.droppable({
        activeClass: "dragging",
        hoverClass: "hover",
        tolerance: "touch",
        accept: "#friends li",
        activate: function (event, ui) {
            var existed = false,
            username = ui.draggable.data("Account").username,
            array = $(this).siblings().children("a");
            $.each(array, function (i,a) {
                if(a.title === username) {
                    existed =true;
                    return false; // stop iteration
                }
            });

            if(existed) {
                $(this).addClass("existed");
            } else {
                $(this).removeClass("existed");
            }

        },
        deactivate: function () {
            $(this).removeClass("existed");
        },
        drop: function(event, ui) {
            if($(this).hasClass("existed")) {
                $(this).removeClass("existed");
                return;
            }
            var room = $(this).parents(".chat-room");
            if(!room.hasClass("local-room")) {
                var id = room.attr("id");
                addParticipant(id, [ui.helper.children("a").attr("title")]);
            }

            $(this).after($("<li/>", {
                "class": "active",
                html: $("<a />", {
                    text: ui.helper.text(),
                    title: ui.helper.children("a").attr("title"),
                    href: "#"
                })
            }));
            var currentTab= $("#rooms li.ui-tabs-selected > a");
            var count = $(this).siblings().length;
            var title = "";
            switch(count) {
                case 1: // this is the first
                    currentTab.text(ui.helper.text());
                    break;
                case 2: // 2 nguoi
                    title = "(2) " + currentTab.text() + ", " + ui.helper.text();
                    currentTab.text(title);
                    break;
                default:// more than 2
                    title = currentTab.text().replace(/^\((\d*)\)/,function () {
                        return "("+(+arguments[1]+1)+")";
                    });
                    ;
                    title += ", " + ui.helper.text();
                    currentTab.text(title);
                    break;

            }
        }
    });
}
addDroppablePeople($(".drop-people-here"));

// event search
$("#search").keyup(function (e) {
    var keyword = this.value;
    searchFriend(keyword);
});





// Vietnamese characters for accent insentive search
var vnkey = {
    'a': '[aáàảãạâấầẩẫậăắằẳẵặ]',
    'e': '[eéèẻẽẹêếềểễệ]',
    'd': '[dđ]',
    'i': '[iíìỉĩị]',
    'o': '[oóòỏõọôốồổỗộơớờởỡợ]',
    'u': '[uúùủũụưứừửữự]',
    'y': '[yýỳỷỹỵ]'
};

var searchFriend = function(keyword) {
    var regx = (function(query) {
        // create regular expression to highlight keyword
        pattern = '';
        for (j = 0; j < query.length; ++j) {
            ch = query[j];
            if (vnkey.hasOwnProperty(ch)) {
                pattern += vnkey[ch];
            } else {
                pattern += ch;
            }
        }
        return new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + pattern + ")(?![^<>]*>)(?![^&;]+;)", "gi");
    })(keyword);

    // reset
    var lis = $("#friends > li");
    lis.show();

    // iterate all friends
    var notmatch = $.grep(lis, function (li) {
        var account = $(li).data("Account");
        if(account.display.match(regx) || account.username.match(regx)) {
            return true;
        }
        else return false;
    }, true);

    $(notmatch).hide();
}




// create room
$("#createRoom > a").click( function (e) {
    var id = $.now().toString(36),
    div = createRoomHTML("room-"+id);

    $("#rooms").append(div);

    addDroppablePeople($(".drop-people-here", "#room-"+id));

    // hack to escape default switch to + tab
    $("#room-"+id).hide();
    setTimeout(function () {
        $("#rooms").tabs("add","#room-"+id,"empty", 0).tabs( "select" , 0 ) ;
        $("#room-"+id).show();
    }, 1);
});

// leave room
$("#rooms > ul > li .ui-icon-close").live("click", function() {
    var ok = confirm ("You are about to leave this room.\n"+
        "After leaving a room, you cannot receive any message from this room\n\n"+
        "Are you sure to continue?");
    if(!ok) return;
    var $this = $(this);
    leaveRoom($(this).prev().attr("href").substring(1), function() {
        var index = $( "li", tabs ).index( $this.parent() );
        tabs.tabs( "remove", index );
    }, function() {
        var index = $( "li", tabs ).index( $this.parent() );
        tabs.tabs( "remove", index );
    });
    
});

var createRoomHTML = function (id) {
    return '' +
    '    <div id="'+id+'" class="chat-room local-room">\n' +
    '        <div class="participants">\n' +
    '            <ul class="pills">\n' +
    '                <li class="active drop-people-here"><a title="Drag people here"></a></li>\n' +
    '            </ul>\n' +
    '        </div>\n' +
    '        <div  class="chat-content">\n' +
    '            <p>Add participant and start chatting</p>\n' +
    '        </div>\n' +
    '        <div class="input-wrapper">\n' +
    '             <textarea class="message-input" placeholder="type your message here and hit send"></textarea>\n' +
    '             <a href="javascript:void(0);" title="send" class="btn large primary">Send</a>\n' +
    '         </div>\n' +
    '    </div>\n';
}


var friends = [];

var getOnlinePeople = function(callback) {
    $.ajax({
        url: "http://localhost:8084/ChatServer/onlineList.jsp",
        dataType: "xml",
        success: function(users) {
            users = $("user", users);
            friends = [];
            $.each(users, function (i, user) {
                user = $(user);
                friends.push(new Account(user.children("username").text(), user.children("displayname").text(), true));
            });
            if(typeof callback === "function") {
                callback();
            }
        }
    });

}



var updateFriendlist = function() {
    getOnlinePeople(function() {
        var ul = $("#friends");

        $.each(friends, function (i, friend){
            if(friend.username === me.username) {
                return true;
            }
            // tim xem thang nay co trong list chua
            var li = $("li>a[title='"+friend.username+"']", ul).parent();

            // neu chua co -> moi online -> add vào
            if(li.length == 0) {
                li = $("<li/>", {
                    html: $("<a />", {
                        text: friend.display,
                        title: friend.username,
                        href: "#"
                    })
                })
                .addClass("syncd-down") // danh dau la em nay vua dc update
                .data("Account", friend)
                .draggable({
                    helper: 'clone',
                    zIndex: 10
                });
                ul.append(li);
            } else {
                // da online tu truoc
                li.addClass("syncd-down");
            }

        });

        $("li:not(.syncd-down)", ul).remove();
        $(".syncd-down").removeClass("syncd-down");
    });



};
var updateFriendInt = setInterval(updateFriendlist, 1000);
updateFriendlist();

var leaveRoom = function (roomID, success, error) {
    $.ajax({
        url: "ChatController?btnAction=leave",
        data: {
            roomID: roomID
        },
        type: "POST",
        success: function() {
            if(success && typeof success == "function") {
                success();
            }
        },
        error: function() {
            if(error && typeof error == "function") {
                error();
            }
        }
    });
}

var rooms = [];
var getMessage = function (roomID, lastUpdate, success, error) {
    console.log("1 "+new Date().getTime(), !!rooms[roomID]);
    if(!!rooms[roomID]) {
        return;
    }
    console.log("getmessage", roomID, !!rooms[roomID]);
    
    rooms[roomID] = true;
    console.log("2 "+new Date().getTime(), !!rooms[roomID]);
    $.ajax({
        url: "ChatController?btnAction=getMsg",
        data: {
            roomID: roomID,
            lastUpdate : lastUpdate
        },
        dataType: "xml",
        success: function(xml) {
            if(success && typeof success == "function") {
                success(xml);
            }
            rooms[roomID] = false;
            console.log("3 "+new Date().getTime(), rooms[roomID]);
        },
        error: function(xml) {
            if(error && typeof error == "function") {
                error(xml);
            }
            rooms[roomID] = false;
        }
    });
}

var gettingRooms = false;
var getRooms = function (success) {
    if(gettingRooms) {
        return;
    }
    gettingRooms = true;
    $.ajax({
        url: "ChatController?btnAction=getRooms",
        dataType: "xml",
        success: function(xml) {
            if(success && typeof success == "function") {
                success(xml);
            }
            gettingRooms = false
        },
        error: function () {
            gettingRooms = false;
        }
    });

}

var sendMessage = function (roomID, message, cb) {
    $("#"+roomID +" .message-input").prop("disabled","disabled");
    $.post("ChatController?btnAction=sendMsg", {
        roomID: roomID,
        msg: (message.removeTags().replace("\n","<br />"))
    }, function() {
        if(cb && typeof cb == "function") {
            cb();
        }
        $("#"+roomID +" .message-input").removeProp("disabled");
    });
};

var createRoom = function (callback) {
    $.getJSON("ChatController?btnAction=create", {}, function (data) {
        if(callback && typeof callback == "function") {
            callback(data);
        }
    })
};

var addParticipant = function (roomID, participants, callback) {
    $.post("ChatController?btnAction=join", {
        roomID : roomID,
        joiner : participants.join(",")
    }, function () {
        if(callback && typeof callback == "function") {
            callback();
        }
    })
}

$(".input-wrapper > a").live("click", function () {
    var input = $(".message-input", this.parentElement);
    var message = $.trim(input.val());

    // neu ko viet gi thi thoi
    if( message == "") {
        return;
    }

    var room = $(this).parents(".chat-room");
    var participants = $(".participants > ul > li:not(.drop-people-here)", room);
    var a = $("#rooms > ul > li > a[href=#" + room.attr("id") + "]");

    if(participants.length) {
        // neu co participant va room la local thi tao room, xong send message
        if(room.hasClass("local-room")) {
            createRoom(function(data) {
                room.attr("id", data.roomID);
                room.data("lastUpdate",data.lastUpdate || 0);
                a.attr("href", "#"+data.roomID);

                addParticipant(data.roomID, $.map(participants.find("a"),function (e) {
                    return e.title
                }) );

                room.removeClass("local-room");
                sendMessage(data.roomID, message, function() {
                    input.val("");
                });
            });


        } else {
            sendMessage(room.attr("id"), message, function() {
                input.val("");
            });
        }
    }
})

var updateRooms = function () {
    getRooms(function (xml) {
        var rooms = $("room", xml)
        $.each(rooms, function(i,room) {
            var id = $(room).attr("id");
            var localRoom = $("#rooms .chat-room#"+id);

            // neu co room do roi
            if(localRoom.length) {
                ///console.log("before updating: "+localRoom.data("lastUpdate"));
                getMessage(id, localRoom.data("lastUpdate"), function (roomData) {
                    localRoom.data("lastUpdate", updateUIRoom(id, roomData) );
                });
            } else { // neu chua co room
                // add room
                //console.log("before updating: "+localRoom.data("lastUpdate"));
                getMessage(id, localRoom.data("lastUpdate"), function (roomData) {
                    var lastUpdate = updateUIRoom(id, roomData, true);
                    $("#rooms .chat-room#"+id).data("lastUpdate", lastUpdate );
                });
            }

        });

    });

}
var updateUIRoom = function (id, roomData, createRoom) {
    // process xml
    var everyOne = $("participant", roomData);
    var notMe = $.grep(everyOne, function (e) {
        return $("username", e).text() !== me.username;
    });
    var participants = $.map(notMe, function (e) {
        return new Account(
            $(e).children("username").text(),
            $(e).children("displayname").text()
            );
    });

    var tabTitle = (function (participants) {
        switch(participants.length) {
            case 0:
                return "empty";
            case 1:
                return participants[0].display;
            default:
                return "("+ participants.length + ") "
                + $.map(participants, function(p) {
                    return p.display;
                }).join(",");
        }
    })(participants);

    if(createRoom && $("#"+id).length == 0) {
        var div = createRoomHTML(id);
        $("#rooms").append(div);
        addDroppablePeople($(".drop-people-here", "#"+id));
        $("#rooms").tabs("add","#"+id,tabTitle, 0);//.tabs( "select" , 0 )
    } else {
        $("#rooms a[href=#"+id+"]").text(tabTitle);
    }

    var room = $(".chat-room#"+id);
    if(room.length==0) {
        return;
    }
    room.removeClass("local-room");

    var msg = $.map($("message", roomData), function(m) {
        m = $(m);
        return {
            sentTime: m.attr("sentTime"),
            sender : {
                username: $("username", m).text(),
                display: $("username", m).next().text()
            },
            content: $("content", m).text()
        }
    });

    $.each(msg, function(i,m) {
        var a = new Date(+m.sentTime);
        $(".chat-content", room).append(
            '<p>\n' +
            '   <span class="display-name" title="'+m.sender.username+'">'+m.sender.display+'</span> '+
            '   <span class="time">(' + a.toDateString() + " " + a.toLocaleTimeString() + ')</span>:' +
            '   <span class="message-text">' + emoticon(m.content)+'</span></p>'
            );
    });
    if(msg.length) {
        room.find(".chat-content").scrollTop(400);
    }

    //$(".participants > ul > li:not(.drop-people-here)", room).remove();
    $.each(participants, function(i,p){
        var _p /* local participant */ = room.find("a[title=" + p.username +"]").parent();
        while(_p.length > 1) {
            _p = _p.first();
        }
        if(_p.length) {
            // neu co participant do roi
            _p.addClass("syncd-down");
        } else {
            $("<li />", {
                html: $("<a />", {
                    text: p.display,
                    title: p.username
                }),
                "class": "active syncd-down"
            }).appendTo($(".participants > ul"));
        }

    });
    $(".participants > ul > li:not(.drop-people-here):not(.syncd-down)", room).remove();
    $(".participants > ul > li.syncd-down", room).removeClass("syncd-down");

    if(msg.length) {
        console.log($("room", roomData).attr("lastUpdate"),msg,participants, roomData);
    }
    return $("room", roomData).attr("lastUpdate");
}
var refreshRoomsInterval = setInterval(updateRooms, 500);

var emoticon = function (s) {
    var p = '<img src="http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons7/';
    var u = '.gif\" style=\"border:0; margin:0; padding:0;\"/>';

    s = s.replace(/(<[^>]*:(?=(p|d|l)))/ig, "$1 ");
    s = s.replace(/x_x/ig, p+"109"+u);
    s = s.replace(/:!!/g, p+"110"+u);
    s = s.replace(/\\m\//g, p+"111"+u);
    s = s.replace(/:-q/g, p+"112"+u);
    s = s.replace(/:-bd/g, p+"113"+u);
    s = s.replace(/\^#\(\^/g, p+"114"+u);
    s = s.replace(/:bz/g, p+"115"+u);
    s = s.replace(/:\)>-/g, p+"67"+u);
    s = s.replace(/:o3/g, p+"108"+u);
    s = s.replace(/:-\?\?/g, p+"106"+u);
    s = s.replace(/%-\(/g, p+"107"+u);
    s = s.replace(/:@\)/g, p+"49"+u);
    s = s.replace(/3:-o/ig, p+"50"+u);
    s = s.replace(/:\(\|\)/g, p+"51"+u);
    s = s.replace(/~:>/g, p+"52"+u);
    s = s.replace(/@\};-/g, p+"53"+u);
    s = s.replace(/%%-/g, p+"54"+u);
    s = s.replace(/\*\*==/g, p+"55"+u);
    s = s.replace(/\(~~\)/g, p+"56"+u);
    s = s.replace(/~o\)/ig, p+"57"+u);
    s = s.replace(/\*-:\)/g, p+"58"+u);
    s = s.replace(/8-x/ig, p+"59"+u);
    s = s.replace(/=:\)/g, p+"60"+u);
    s = s.replace(/>-\)/g, p+"61"+u);
    s = s.replace(/:-?l/ig, p+"62"+u);
    s = s.replace(/\[-o</ig, p+"63"+u);
    s = s.replace(/\$-\)/g, p+"64"+u);
    s = s.replace(/:-"/g, p+"65"+u);
    s = s.replace(/b-\(/ig, p+"66"+u);
    s = s.replace(/\[-x/ig, p+"68"+u);
    s = s.replace(/\\:D\//ig, p+"69"+u);
    s = s.replace(/>:\//g, p+"70"+u);
    s = s.replace(/;\)\)/g, p+"71"+u);
    s = s.replace(/:-@/g, p+"76"+u);
    s = s.replace(/\^:\)\^/g, p+"77"+u);
    s = s.replace(/:-j/ig, p+"78"+u);
    s = s.replace(/\(\*\)/g, p+"79"+u);
    s = s.replace(/o->/ig, p+"72"+u);
    s = s.replace(/o=>/ig, p+"73"+u);
    s = s.replace(/o-\+/ig, p+"74"+u);
    s = s.replace(/\(%\)/g, p+"75"+u);
    s = s.replace(/o:-\)/ig, p+"25"+u);
    s = s.replace(/<:-p/ig, p+"36"+u);
    s = s.replace(/\/:\)/g, p+"23"+u);
    s = s.replace(/:\)\)/g, p+"21"+u);
    s = s.replace(/>:\)/g, p+"19"+u);
    s = s.replace(/<\):\)/g, p+"48"+u);
    s = s.replace(/:\)\]/g, p+"100"+u);
    s = s.replace(/:-?\)/g, p+"1"+u);
    s = s.replace(/:\(\(/g, p+"20"+u);
    s = s.replace(/:-?\(/g, p+"2"+u);
    s = s.replace(/;;\)/g, p+"5"+u);
    s = s.replace(/>:d</ig, p+"6"+u);
    s = s.replace(/:D/ig, p+"4"+u);
    s = s.replace(/:-\//g, p+"7"+u);
    s = s.replace(/:-?x/ig, p+"8"+u);
    s = s.replace(/:">/g, p+"9"+u);
    s = s.replace(/>:-?P/ig, p+"47"+u);
    s = s.replace(/:-?p/ig, p+"10"+u);
    s = s.replace(/:-?\*/g, p+"11"+u);
    s = s.replace(/=\(\(/g, p+"12"+u);
    s = s.replace(/:-o/ig, p+"13"+u);
    s = s.replace(/~x\(/ig, p+"102"+u);
    s = s.replace(/X\(/ig, p+"14"+u);
    s = s.replace(/:-?>/g, p+"15"+u);
    s = s.replace(/B-\)/ig, p+"16"+u);
    s = s.replace(/:-ss/ig, p+"42"+u);
    s = s.replace(/#:-s/ig, p+"18"+u);
    s = s.replace(/:-s/ig, p+"17"+u);
    s = s.replace(/\(:\|/g, p+"37"+u);
    s = s.replace(/:\|/g, p+"22"+u);
    s = s.replace(/=\)\)/g, p+"24"+u);
    s = s.replace(/:-b/ig, p+"26"+u);
    s = s.replace(/=;/g, p+"27"+u);
    s = s.replace(/:-c/ig, p+"101"+u);
    s = s.replace(/:-h/ig, p+"103"+u);
    s = s.replace(/:-t/ig, p+"104"+u);
    s = s.replace(/8->/g, p+"105"+u);
    s = s.replace(/I-\)/ig, p+"28"+u);
    s = s.replace(/8-\|/g, p+"29"+u);
    s = s.replace(/L-\)/ig, p+"30"+u);
    s = s.replace(/:-&amp;/g, p+"31"+u);
    s = s.replace(/:-\$/g, p+"32"+u);
    s = s.replace(/\[-\(/g, p+"33"+u);
    s = s.replace(/:o\)/ig, p+"34"+u);
    s = s.replace(/8-\}/g, p+"35"+u);
    s = s.replace(/=p~/ig, p+"38"+u);
    s = s.replace(/:-\?/g, p+"39"+u);
    s = s.replace(/#-o/ig, p+"40"+u);
    s = s.replace(/=d>/ig, p+"41"+u);
    s = s.replace(/@-\)/g, p+"43"+u);
    s = s.replace(/:\^o/ig, p+"44"+u);
    s = s.replace(/:-w/ig, p+"45"+u);
    s = s.replace(/:-?</g, p+"46"+u);
    s = s.replace(/;-?\)/g, p+"3"+u);
    return s;
}